package com.miracle.tears.util;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/** 文件操作工具类 */
public class FileOperatorUtil {
  /**
   * 通过给定的文件夹路径，拿到对应的内部的文件的名称列表
   *
   * @param dirPath 文件夹路径
   * @return 所有文件名称 集合
   */
  public static List<String> getFileNameByDirPath(String dirPath) {
    // 首先要做边界检查
    if (dirPath == null || dirPath.trim().length() == 0) {
      return null;
    }
    File file = new File(dirPath);
    // file.list 获取文件名称
    String[] fileArray = file.list();
    assert fileArray != null;
    return Arrays.asList(fileArray);
  }

  /**
   * 通过给定的文件夹路径，拿到对应的内部的文件的全路径列表集合
   *
   * @param dirPath 指定文件夹路径
   * @return 文件夹内部所有文件的 全路径集合
   */
  public static List<String> getFilePathByDirPath(String dirPath) {
    // 首先要做边界检查
    if (dirPath == null || dirPath.trim().length() == 0) {
      return null;
    }
    // 定义一个返回的结果 集合变量
    List<String> filePathList = new ArrayList<>();
    File file = new File(dirPath);
    // file.listFiles() 获取该目录下所有文件的全路径
    File[] fileArray = file.listFiles();
    assert fileArray != null;
    // 循环遍历 toString方法
    for (File tempFile : fileArray) {
      filePathList.add(tempFile.toString());
    }
    return filePathList;
  }

  /**
   * 给定一个文本文件路径和编码，拿到其内容对应的List集合
   *
   * @param txtFilePath 文本文件路径
   * @param charset 文件字符集
   * @return 文件内容 转换的 list 集合
   * @throws IOException 全部抛出异常
   */
  public static List<String> getLineList(String txtFilePath, String charset) throws IOException {
    // 注意边界检查
    File file = new File(txtFilePath);
    FileInputStream fis = new FileInputStream(file);
    InputStreamReader isr = new InputStreamReader(fis, charset);
    BufferedReader br = new BufferedReader(isr);

    // 定义一个文件的结果集合
    List<String> txtLineList = new ArrayList<>();
    String templine;
    while ((templine = br.readLine()) != null) {
      txtLineList.add(templine);
    }
    // 关闭最大的流即可
    br.close();
    // 集合形式的文件数据，在一行显示，逗号分割
    return txtLineList;
  }

  /**
   * 给定一个文件夹路径，获取其内部所有文本文件的对应的行集合的汇总集合
   *
   * @param dirPath 指定的文件夹路径
   * @param charset 编码
   * @return 所有文件 对应的数据汇总 集合
   * @throws IOException 所以异常
   */
  public static List<String> getAllLineList4DirPath(String dirPath, String charset)
      throws IOException {
    // 首先拿到该文件夹对应的 所有文件的全路径
    List<String> filePathList = getFilePathByDirPath(dirPath);

    // 定义最终所有文件数据汇总后的总集合
    List<String> allLineList = new ArrayList<>();

    // 遍历文件路径集合，获取对应的文件数据 集合
    for (String txtFilePath : filePathList) {
      // 将每一个文件数据 转换成为集合
      List<String> singleFileLineList = getLineList(txtFilePath, charset);
      // 将所有单个文件集合 汇总到一个大集合中 总数据集合
      allLineList.addAll(singleFileLineList);
    }

    return allLineList;
  }

  /**
   * 将指定行内容写入到指定文件路径当中
   *
   * @param filePath 指定文件路径
   * @param line 一行
   * @throws IOException 抛出IO异常
   */
  public static void writeLineToFile(String filePath, String line, boolean isAppend)
      throws IOException {
    // 文件输出流 追加写出
    FileOutputStream fos = new FileOutputStream(filePath, isAppend);
    // 字节流写出内容，指定编码格式
    fos.write(line.getBytes(StandardCharsets.UTF_8));
    fos.close();
  }

  // 循环遍历文件夹，获取文本文件
  public static void RecGetFiles(File dir, List<File> result, String split) {
    // listFiles()方法的作用如果file是个文件，则返回的是null，如果file是空目录，返回的是空数组，
    // 如果file不是空目录，则返回的是该目录下的文件和目录
    File[] files = dir.listFiles();

    if (files != null) {
      for (File file : files) {
        if (file.isDirectory()) {
          // 如果是目录，递归调用自己
          RecGetFiles(file, result, split);
        }
        // 如果是文件，得到以 .txt 结尾的文件
        if (file.getName().endsWith(split)) {
          // 添加进入文件列表
          result.add(file);
        }
      }
    }
  }

  // 获取评论内容列表(频道目录名称 集合)
  public static List<String> getContentDataList(List<File> result, String str) {
    List<String> ContentDataList = new ArrayList<>();
    for (File file : result) {
      String single = file.getPath();
      // 如果包含 user
      if (single.contains(str)) {
        ContentDataList.add(single);
      }
    }
    return ContentDataList;
  }

  // txt按行切割方法
  public static List<String> getStringList(List<String> list, String coding) throws Exception {
    List<String> lineList = new ArrayList<>();

    for (String str : list) {
      FileInputStream fis = new FileInputStream(str);
      Reader reader = new InputStreamReader(fis, coding);
      BufferedReader br = new BufferedReader(reader);

      String tempLine;
      while ((tempLine = br.readLine()) != null) {
        StringBuilder finalStr = new StringBuilder();
        // 取出中括号内部数据
        String s1 = tempLine.trim().substring(6, tempLine.length() - 1);
        // 按逗号分割 每一项
        String[] s2 = s1.trim().split(",");
        for (String string : s2) {
          // 按 = 号分割 一个键值对中的数据
          String[] s3 = string.trim().split("=");
          // 取出字段是 id 和 remark 的值的数据 添加到结果集中
          if (s3[0].equals("id") || s3[0].equals("remark")) {
            finalStr.append(s3[1]).append("\t");
          }
        }
        lineList.add(finalStr.toString());
      }
    }
    return lineList;
  }

  // 写入文件
  public static void writeFile(String str, String path, String charset) throws Exception {
    FileOutputStream fos = new FileOutputStream(path, true);
    OutputStreamWriter wr = new OutputStreamWriter(fos, charset);
    BufferedWriter bw = new BufferedWriter(wr);
    bw.write(str);
    bw.newLine();
    bw.flush();
    bw.close();
  }

  // 按xml格式切分后的结果     输入，文件列表     inputCharset编码格式
  public static List<String> getXMLList(List<String> list, String inputCharset) throws Exception {
    List<String> lineList = new ArrayList<>();
    for (String str : list) {
      FileInputStream fis = new FileInputStream(str);
      Reader reader = new InputStreamReader(fis, inputCharset);
      BufferedReader br = new BufferedReader(reader);

      String tempLine;
      while ((tempLine = br.readLine()) != null) {
        String text = tempLine;
        text = text.replace("<content>", "<content><![CDATA[");
        text = text.replace("</content>", "]]></content>");

        Document document = DocumentHelper.parseText(text);
        Element root = document.getRootElement();

        String content = root.elementText("content");
        String time = root.elementText("time");
        String repostsCount = root.elementText("repostsCount");
        String commentsCount = root.elementText("commentsCount");

        String[] strPath = str.split("\\\\");
        System.err.println(Arrays.toString(strPath));
        String[] contentId = strPath[7].split("\\.");
        System.err.println(Arrays.toString(contentId));
        String finalStr =
            contentId[0]
                + "\t"
                + content
                + "\t"
                + time
                + "\t"
                + repostsCount
                + "\t"
                + commentsCount;
        lineList.add(finalStr);
        System.out.println(finalStr);
      }
    }
    return lineList;
  }
}
